package com.norns.torque.view

import android.bluetooth.BluetoothAdapter
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.widget.Toast
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.gyf.immersionbar.ImmersionBar
import com.hi.dhl.binding.viewbind
import com.norns.torque.BluetoothViewModel
import com.norns.torque.R
import com.norns.torque.bluetooth.ChatServer
import com.norns.torque.databinding.ActivityLoopValueBinding
import com.norns.torque.entrty.DeviceConfig
import com.norns.torque.utils.AppConstant
import com.norns.torque.utils.AppContext
import com.norns.torque.utils.DataConversion
import timber.log.Timber
import java.lang.Float.intBitsToFloat
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter


class LoopValueActivity : AppCompatActivity() {
    private val binding: ActivityLoopValueBinding by viewbind()
    private val bluetoothViewModel: BluetoothViewModel by viewModels()
    private var offset:Float=0f
    companion object {
        const val timeRefresh = 124
        const val countdown = 387
        const val loopTrack = 389
        //const val random = 340
    }
    override fun attachBaseContext(newBase: Context?) {
        super.attachBaseContext(newBase)
        overrideFontScale(newBase)
    }

    /**
     * 重置配置 fontScale：保持字体比例不变，始终为 1.
     */
    private fun overrideFontScale(context: Context?) {
        if (context == null) return
        context.resources.configuration.let {
            it.fontScale = 1f // 保持字体比例不变，始终为 1.
            applyOverrideConfiguration(it) // 应用新的配置
        }
    }

    private val handler: Handler = object : Handler(Looper.myLooper()!!) {
        override fun handleMessage(msg: android.os.Message) {
            when(msg.what){
                timeRefresh->{
                    updateTime()
                    sendEmptyMessageDelayed(timeRefresh,1000)
                }
                countdown->{//设备重新连接
                    if (!bluetoothViewModel.isConnected()) {
                        Toast.makeText(this@LoopValueActivity, "设备连接失败", Toast.LENGTH_SHORT).show()
                    }
                }
                loopTrack->{//获取TrackValue
                    if (bluetoothViewModel.isConnected()) { //是连接状态
                        bluetoothViewModel.getTrackValue()
                        sendEmptyMessageDelayed(loopTrack, 100)
                    }
                }
//                random ->{
//                    val randomFloat: Float = Random.nextFloat()
//                    val randomInt: Int = Random.nextInt(2,25)
//                    val value= randomInt.toFloat()+randomFloat
//                    //defaultValue+=3f
//                    binding.chartView.setTrackValue(value)
//                }
            }
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initView()
        initData()
        subscribeToModel()
    }

    override fun onResume() {
        super.onResume()
        bluetoothViewModel.setResultMessageState(false)
        bluetoothViewModel.readDeviceValue()
        bluetoothViewModel.startGetDeviceRssi()
    }

    private fun initView() {
        ImmersionBar.with(this).statusBarColor(R.color.main)
            .navigationBarColor(R.color.main)
            .autoStatusBarDarkModeEnable(true,0.2f)
            .init()
        ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        binding.tvContent.text="量程:${DeviceConfig.range}"
        val blackColor = getColor(R.color.green_color)
        binding.tvContentState.text = "已连接"
        binding.tvContentState.setTextColor(blackColor)
        binding.btnBack.setOnClickListener {
            bluetoothViewModel.disconnect()
            finish()
        }

        binding.tvValue.setOnClickListener {
            binding.chartView.setSowMaxText()
        }
        binding.btnMore.setOnClickListener {
            bluetoothViewModel.disconnect()
            if (ChatServer.contentType==ChatServer.NetWork) {
                startActivity(Intent(this@LoopValueActivity, WiFiDeviceActivity::class.java))
            }else{
                startActivity(Intent(this@LoopValueActivity, ScanActivity::class.java))
            }
            finish()
        }
        binding.tvPeakValue.setOnClickListener {
            handler.removeCallbacksAndMessages(null)
            //handler.sendEmptyMessageDelayed(random, 200)
            if (bluetoothViewModel.isConnected()){
                //峰值模式
                startActivity(Intent(this@LoopValueActivity, PeakValueActivity::class.java))
                finish()
            }else{
                Toast.makeText(this@LoopValueActivity, "设备连接已断开", Toast.LENGTH_SHORT).show()
            }
        }
        binding.tvSetting.setOnClickListener {
            handler.removeMessages(loopTrack)
            bluetoothViewModel.stopGetDeviceRssi()
            startActivity(Intent(this@LoopValueActivity, SettingActivity::class.java))
        }
    }

    private fun initData() {
        handler.sendEmptyMessage(timeRefresh)
        updateTime()
    }

    private fun updateTime() {
        val localDateTime = LocalDateTime.now()
        val f2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
        val contentTime = localDateTime.format(f2)
        binding.tvTime.text = contentTime
    }

    override fun onDestroy() {
        bluetoothViewModel.stopGetDeviceRssi()
        super.onDestroy()
        handler.removeCallbacksAndMessages(null)
    }

    private fun subscribeToModel() {
        bluetoothViewModel.connectionState.observe(this) { value ->
            if (value== AppConstant.connectionField) {
                binding.tvContentState.text = "连接已断开"
                val errorColor = getColor(R.color.error_color)
                binding.tvContentState.setTextColor(errorColor)
            } else if (value==AppConstant.connectionSuccess)  {
                val blackColor = getColor(R.color.green_color)
                binding.tvContentState.text = "已连接"
                binding.tvContentState.setTextColor(blackColor)
            }
        }
        ChatServer.contentDevice.observe(this){value->
            binding.tvDeviceMac.text = value.address
        }
        bluetoothViewModel.bluetoothRssi.observe(this) { vaule ->
            binding.tvDistance.text = "${vaule}dbm"
        }
        bluetoothViewModel.bluetoothState.observe(this) { value ->
            if (value == BluetoothAdapter.STATE_OFF) {
                binding.tvContentState.text = "蓝牙已关闭"
                val errorColor = getColor(R.color.error_color)
                binding.tvContentState.setTextColor(errorColor)
                ChatServer.disconnect()
                return@observe
            }
            if (value == BluetoothAdapter.STATE_ON) {
                binding.tvContentState.text = "正在连接蓝牙..."
                val errorColor = getColor(R.color.blue_color)
                binding.tvContentState.setTextColor(errorColor)
                ChatServer.autoConnection()
                handler.sendEmptyMessageDelayed(countdown, 6000)
            }
        }
        //获取设备发送的消息
        bluetoothViewModel.messages.observe(this) { messages ->
            if (messages.startsWith("AA44")){
                val cmdCodeLengthStr = messages.substring(6, 8)
                val cmdCodeLength = Integer.parseInt(cmdCodeLengthStr, 16) * 2
                Timber.d("命令长度${cmdCodeLength}")
                if (messages.length <(8 + cmdCodeLength)){
                    lastMessage=messages
                }else{
                    praceMessage(messages)
                }
            }else{
                if (messages.endsWith("0D0A") && !TextUtils.isEmpty(lastMessage)){
                    lastMessage+=messages
                    Timber.d("2222:${lastMessage}")
                    praceMessage(lastMessage)
                }
            }
        }
    }
    private var lastMessage:String=""
    private fun praceMessage(messageText:String){
        lastMessage=""
        if (messageText.startsWith("AA44")) {
            val cmdCodeStr = messageText.substring(4, 6)
            val cmdCode = cmdCodeStr.toInt(16)
            val cmdCodeLengthStr = messageText.substring(6, 8)
            val cmdCodeLength = cmdCodeLengthStr.toInt(16) * 2
            val cmdDataStr = try{
                messageText.substring(8, 8 + cmdCodeLength)
            }catch (e:Exception){
                ""
            }
            if (cmdDataStr.isEmpty()){// 获取剪贴板管理器
                val clipboard: ClipboardManager? = AppContext.context.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
                if (clipboard != null) {
                    // 创建一个剪贴数据对象并设置要复制的文本
                    val clip = ClipData.newPlainText("label", messageText)
                    // 将剪贴数据对象复制到剪贴板
                    clipboard.setPrimaryClip(clip)
                    // 提示用户复制成功
                    //Toast.makeText(applicationContext, "已复制到剪贴板", Toast.LENGTH_SHORT).show()
                }
                Toast.makeText(this, "设备命令错误", Toast.LENGTH_SHORT).show()
                return
            }
            when (cmdCode) {
                255 ->{
                    bluetoothViewModel.setResultMessageState(true)
                    //获取设备Track值
                    bluetoothViewModel.getTrackValue()
                    handler.sendEmptyMessageDelayed(loopTrack,500)
                    praceConfig(cmdDataStr)
                }
                8 -> {
                    val trackValue = intBitsToFloat(Integer.reverseBytes(Integer.parseUnsignedInt(cmdDataStr, 16)))
                    val number=(Math.round(trackValue*1000)/1000f)
                    binding.chartView.setTrackValue(number)
                    binding.tvValue.text=number.toString()
                    Timber.i( "设备Track值:${trackValue} ${cmdDataStr} ${number} ${offset}")
                    val upValue=DeviceConfig.targetValue+offset
                    val dowValue=DeviceConfig.targetValue-offset
                    if (number<dowValue){
                        val blackColor = getColor(R.color.black)
                        binding.tvValue.setTextColor(blackColor)
                    }else if (number>upValue){
                        val errorColor = getColor(R.color.error_color)
                        binding.tvValue.setTextColor(errorColor)
                    }else{
                        val greenColor = getColor(R.color.green_color)
                        binding.tvValue.setTextColor(greenColor)
                    }
                }
            }
        }
    }
    private fun praceConfig(cmdDataStr:String){
        val rangValueStr=cmdDataStr.substring(0,4)
        DeviceConfig.range=rangValueStr.toInt(16)
        binding.tvContent.text="量程:${DeviceConfig.range}"
        //目标值
        val targetValueStr=cmdDataStr.substring(4,8)
        Timber.d("设备目标值:${targetValueStr}")
        DeviceConfig.targetValue=targetValueStr.toInt(16)
        //精度
        val precisionValueStr=cmdDataStr.substring(8,10)
        Timber.d("设备精度值:${precisionValueStr}")
        DeviceConfig.precisionValue=precisionValueStr.toInt(16)
        //单位
        val unitStr=cmdDataStr.substring(10,12)
        Timber.d("设备单位值:${unitStr}")
        DeviceConfig.unitValue=unitStr.toInt(16)

        if (cmdDataStr.length<=24){
            DeviceConfig.bluetoothName=ChatServer.contentDevice.value?.name?:"Unknown"
            binding.tvDeviceName.text = DeviceConfig.bluetoothName
        }else {
            val deviceNameCode = cmdDataStr.substring(24)
            val deviceName=DataConversion.hexStringToOriginalString(deviceNameCode)
            DeviceConfig.bluetoothName= deviceName
            binding.tvDeviceName.text = deviceName
        }
        offset=DeviceConfig.targetValue*(DeviceConfig.precisionValue/100f)
    }
}